package com.lifeverse.service;

import com.lifeverse.entity.BehaviorPattern;
import com.lifeverse.entity.PatternAlert;
import com.lifeverse.entity.enums.AlertSeverity;
import com.lifeverse.entity.enums.AlertStatus;
import com.lifeverse.entity.enums.PatternType;
import com.lifeverse.repository.BehaviorPatternRepository;
import com.lifeverse.repository.PatternAlertRepository;
import com.lifeverse.util.JsonUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.math3.stat.regression.SimpleRegression;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 模式变化趋势分析和预警服务
 * 分析行为模式的变化趋势并生成预警
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class PatternTrendAnalysisService {

    private final BehaviorPatternRepository behaviorPatternRepository;
    private final PatternAlertRepository patternAlertRepository;
    private final JsonUtils jsonUtils;

    // 趋势分析配置
    private static final int TREND_ANALYSIS_DAYS = 14;
    private static final double SIGNIFICANT_CHANGE_THRESHOLD = 0.3;
    private static final double CRITICAL_CHANGE_THRESHOLD = 0.5;
    private static final int MIN_DATA_POINTS = 5;

    /**
     * 分析所有生命体的模式趋势
     */
    @Scheduled(fixedRate = 3600000) // 每小时执行一次
    @Transactional
    public void analyzeAllPatternTrends() {
        log.info("开始分析所有生命体的模式趋势");
        
        try {
            // 获取所有活跃的生命体ID
            LocalDateTime since = LocalDateTime.now().minus(TREND_ANALYSIS_DAYS, ChronoUnit.DAYS);
            List<Long> activeLifeEntityIds = behaviorPatternRepository.findActivePatternsSince(since)
                    .stream()
                    .map(BehaviorPattern::getLifeEntityId)
                    .distinct()
                    .collect(Collectors.toList());
            
            int totalAlerts = 0;
            for (Long lifeEntityId : activeLifeEntityIds) {
                List<PatternAlert> alerts = analyzePatternTrends(lifeEntityId);
                totalAlerts += alerts.size();
            }
            
            log.info("趋势分析完成，共分析 {} 个生命体，生成 {} 个趋势预警", 
                    activeLifeEntityIds.size(), totalAlerts);
            
        } catch (Exception e) {
            log.error("分析模式趋势时发生错误", e);
        }
    }

    /**
     * 分析特定生命体的模式趋势
     */
    @Transactional
    public List<PatternAlert> analyzePatternTrends(Long lifeEntityId) {
        log.info("开始分析生命体 {} 的模式趋势", lifeEntityId);
        
        List<PatternAlert> alerts = new ArrayList<>();
        
        try {
            // 获取历史模式数据
            LocalDateTime since = LocalDateTime.now().minus(TREND_ANALYSIS_DAYS, ChronoUnit.DAYS);
            List<BehaviorPattern> historicalPatterns = behaviorPatternRepository
                    .findActivePatternsSince(since)
                    .stream()
                    .filter(p -> p.getLifeEntityId().equals(lifeEntityId))
                    .collect(Collectors.toList());
            
            if (historicalPatterns.size() < MIN_DATA_POINTS) {
                log.info("生命体 {} 的历史数据不足，跳过趋势分析", lifeEntityId);
                return alerts;
            }
            
            // 1. 分析置信度趋势
            alerts.addAll(analyzeConfidenceTrend(lifeEntityId, historicalPatterns));
            
            // 2. 分析频率趋势
            alerts.addAll(analyzeFrequencyTrend(lifeEntityId, historicalPatterns));
            
            // 3. 分析异常分数趋势
            alerts.addAll(analyzeAnomalyScoreTrend(lifeEntityId, historicalPatterns));
            
            // 4. 分析模式多样性趋势
            alerts.addAll(analyzeDiversityTrend(lifeEntityId, historicalPatterns));
            
            // 5. 分析模式生命周期趋势
            alerts.addAll(analyzeLifecycleTrend(lifeEntityId, historicalPatterns));
            
            // 保存预警
            if (!alerts.isEmpty()) {
                alerts = patternAlertRepository.saveAll(alerts);
                log.info("为生命体 {} 生成了 {} 个趋势预警", lifeEntityId, alerts.size());
            }
            
        } catch (Exception e) {
            log.error("分析生命体 {} 模式趋势时发生错误", lifeEntityId, e);
        }
        
        return alerts;
    }

    /**
     * 分析置信度趋势
     */
    private List<PatternAlert> analyzeConfidenceTrend(Long lifeEntityId, List<BehaviorPattern> patterns) {
        List<PatternAlert> alerts = new ArrayList<>();
        
        try {
            // 按时间排序
            patterns.sort(Comparator.comparing(BehaviorPattern::getLastDetectedAt));
            
            // 准备时间序列数据
            List<TimeSeriesPoint> timeSeries = patterns.stream()
                    .map(p -> new TimeSeriesPoint(
                            ChronoUnit.HOURS.between(patterns.get(0).getLastDetectedAt(), p.getLastDetectedAt()),
                            p.getConfidenceScore()
                    ))
                    .collect(Collectors.toList());
            
            // 计算趋势
            TrendAnalysisResult trend = calculateTrend(timeSeries);
            
            if (Math.abs(trend.getSlope()) > SIGNIFICANT_CHANGE_THRESHOLD) {
                AlertSeverity severity = Math.abs(trend.getSlope()) > CRITICAL_CHANGE_THRESHOLD ? 
                        AlertSeverity.HIGH : AlertSeverity.MEDIUM;
                
                String direction = trend.getSlope() > 0 ? "上升" : "下降";
                
                PatternAlert alert = createTrendAlert(
                        lifeEntityId,
                        "置信度趋势变化",
                        String.format("检测到置信度%s趋势，变化率: %.2f%%，R²: %.3f", 
                                direction, trend.getSlope() * 100, trend.getRSquared()),
                        severity,
                        Math.abs(trend.getSlope()),
                        trend
                );
                alerts.add(alert);
            }
            
        } catch (Exception e) {
            log.error("分析置信度趋势时发生错误", e);
        }
        
        return alerts;
    }

    /**
     * 分析频率趋势
     */
    private List<PatternAlert> analyzeFrequencyTrend(Long lifeEntityId, List<BehaviorPattern> patterns) {
        List<PatternAlert> alerts = new ArrayList<>();
        
        try {
            // 按日期聚合频率
            Map<String, Integer> dailyFrequency = patterns.stream()
                    .collect(Collectors.groupingBy(
                            p -> p.getLastDetectedAt().toLocalDate().toString(),
                            Collectors.summingInt(BehaviorPattern::getFrequency)
                    ));
            
            if (dailyFrequency.size() < MIN_DATA_POINTS) {
                return alerts;
            }
            
            // 准备时间序列数据
            List<String> sortedDates = dailyFrequency.keySet().stream().sorted().collect(Collectors.toList());
            List<TimeSeriesPoint> timeSeries = new ArrayList<>();
            
            for (int i = 0; i < sortedDates.size(); i++) {
                String date = sortedDates.get(i);
                timeSeries.add(new TimeSeriesPoint(i, dailyFrequency.get(date).doubleValue()));
            }
            
            // 计算趋势
            TrendAnalysisResult trend = calculateTrend(timeSeries);
            
            if (Math.abs(trend.getSlope()) > SIGNIFICANT_CHANGE_THRESHOLD) {
                AlertSeverity severity = Math.abs(trend.getSlope()) > CRITICAL_CHANGE_THRESHOLD ? 
                        AlertSeverity.HIGH : AlertSeverity.MEDIUM;
                
                String direction = trend.getSlope() > 0 ? "增加" : "减少";
                
                PatternAlert alert = createTrendAlert(
                        lifeEntityId,
                        "活动频率趋势变化",
                        String.format("检测到活动频率%s趋势，变化率: %.2f，R²: %.3f", 
                                direction, trend.getSlope(), trend.getRSquared()),
                        severity,
                        Math.abs(trend.getSlope()),
                        trend
                );
                alerts.add(alert);
            }
            
        } catch (Exception e) {
            log.error("分析频率趋势时发生错误", e);
        }
        
        return alerts;
    }

    /**
     * 分析异常分数趋势
     */
    private List<PatternAlert> analyzeAnomalyScoreTrend(Long lifeEntityId, List<BehaviorPattern> patterns) {
        List<PatternAlert> alerts = new ArrayList<>();
        
        try {
            // 过滤有异常分数的模式
            List<BehaviorPattern> anomalyPatterns = patterns.stream()
                    .filter(p -> p.getAnomalyScore() != null)
                    .sorted(Comparator.comparing(BehaviorPattern::getLastDetectedAt))
                    .collect(Collectors.toList());
            
            if (anomalyPatterns.size() < MIN_DATA_POINTS) {
                return alerts;
            }
            
            // 准备时间序列数据
            List<TimeSeriesPoint> timeSeries = anomalyPatterns.stream()
                    .map(p -> new TimeSeriesPoint(
                            ChronoUnit.HOURS.between(anomalyPatterns.get(0).getLastDetectedAt(), p.getLastDetectedAt()),
                            p.getAnomalyScore()
                    ))
                    .collect(Collectors.toList());
            
            // 计算趋势
            TrendAnalysisResult trend = calculateTrend(timeSeries);
            
            // 异常分数上升趋势需要特别关注
            if (trend.getSlope() > SIGNIFICANT_CHANGE_THRESHOLD) {
                AlertSeverity severity = trend.getSlope() > CRITICAL_CHANGE_THRESHOLD ? 
                        AlertSeverity.CRITICAL : AlertSeverity.HIGH;
                
                PatternAlert alert = createTrendAlert(
                        lifeEntityId,
                        "异常行为增加趋势",
                        String.format("检测到异常行为增加趋势，异常分数上升率: %.2f%%，R²: %.3f", 
                                trend.getSlope() * 100, trend.getRSquared()),
                        severity,
                        trend.getSlope(),
                        trend
                );
                alerts.add(alert);
            }
            
        } catch (Exception e) {
            log.error("分析异常分数趋势时发生错误", e);
        }
        
        return alerts;
    }

    /**
     * 分析模式多样性趋势
     */
    private List<PatternAlert> analyzeDiversityTrend(Long lifeEntityId, List<BehaviorPattern> patterns) {
        List<PatternAlert> alerts = new ArrayList<>();
        
        try {
            // 按日期计算模式多样性
            Map<String, Set<PatternType>> dailyDiversity = patterns.stream()
                    .collect(Collectors.groupingBy(
                            p -> p.getLastDetectedAt().toLocalDate().toString(),
                            Collectors.mapping(BehaviorPattern::getPatternType, Collectors.toSet())
                    ));
            
            if (dailyDiversity.size() < MIN_DATA_POINTS) {
                return alerts;
            }
            
            // 准备时间序列数据
            List<String> sortedDates = dailyDiversity.keySet().stream().sorted().collect(Collectors.toList());
            List<TimeSeriesPoint> timeSeries = new ArrayList<>();
            
            for (int i = 0; i < sortedDates.size(); i++) {
                String date = sortedDates.get(i);
                timeSeries.add(new TimeSeriesPoint(i, dailyDiversity.get(date).size()));
            }
            
            // 计算趋势
            TrendAnalysisResult trend = calculateTrend(timeSeries);
            
            if (Math.abs(trend.getSlope()) > SIGNIFICANT_CHANGE_THRESHOLD) {
                AlertSeverity severity = AlertSeverity.MEDIUM;
                String direction = trend.getSlope() > 0 ? "增加" : "减少";
                
                PatternAlert alert = createTrendAlert(
                        lifeEntityId,
                        "行为多样性趋势变化",
                        String.format("检测到行为多样性%s趋势，变化率: %.2f，R²: %.3f", 
                                direction, trend.getSlope(), trend.getRSquared()),
                        severity,
                        Math.abs(trend.getSlope()),
                        trend
                );
                alerts.add(alert);
            }
            
        } catch (Exception e) {
            log.error("分析多样性趋势时发生错误", e);
        }
        
        return alerts;
    }

    /**
     * 分析模式生命周期趋势
     */
    private List<PatternAlert> analyzeLifecycleTrend(Long lifeEntityId, List<BehaviorPattern> patterns) {
        List<PatternAlert> alerts = new ArrayList<>();
        
        try {
            // 计算模式的平均生命周期
            List<Double> lifecycles = patterns.stream()
                    .filter(p -> p.getDurationMinutes() != null && p.getDurationMinutes() > 0)
                    .map(p -> p.getDurationMinutes().doubleValue())
                    .collect(Collectors.toList());
            
            if (lifecycles.size() < MIN_DATA_POINTS) {
                return alerts;
            }
            
            // 按时间排序并准备时间序列数据
            patterns.sort(Comparator.comparing(BehaviorPattern::getLastDetectedAt));
            List<TimeSeriesPoint> timeSeries = new ArrayList<>();
            
            for (int i = 0; i < Math.min(patterns.size(), lifecycles.size()); i++) {
                timeSeries.add(new TimeSeriesPoint(i, lifecycles.get(i)));
            }
            
            // 计算趋势
            TrendAnalysisResult trend = calculateTrend(timeSeries);
            
            if (Math.abs(trend.getSlope()) > SIGNIFICANT_CHANGE_THRESHOLD) {
                AlertSeverity severity = AlertSeverity.LOW;
                String direction = trend.getSlope() > 0 ? "延长" : "缩短";
                
                PatternAlert alert = createTrendAlert(
                        lifeEntityId,
                        "模式生命周期趋势变化",
                        String.format("检测到模式生命周期%s趋势，变化率: %.2f，R²: %.3f", 
                                direction, trend.getSlope(), trend.getRSquared()),
                        severity,
                        Math.abs(trend.getSlope()),
                        trend
                );
                alerts.add(alert);
            }
            
        } catch (Exception e) {
            log.error("分析生命周期趋势时发生错误", e);
        }
        
        return alerts;
    }

    /**
     * 计算趋势
     */
    private TrendAnalysisResult calculateTrend(List<TimeSeriesPoint> timeSeries) {
        if (timeSeries.size() < 2) {
            return new TrendAnalysisResult(0.0, 0.0, 0.0);
        }
        
        SimpleRegression regression = new SimpleRegression();
        
        for (TimeSeriesPoint point : timeSeries) {
            regression.addData(point.getX(), point.getY());
        }
        
        double slope = regression.getSlope();
        double intercept = regression.getIntercept();
        double rSquared = regression.getRSquare();
        
        return new TrendAnalysisResult(slope, intercept, rSquared);
    }

    /**
     * 创建趋势预警
     */
    private PatternAlert createTrendAlert(Long lifeEntityId, String title, String description,
                                        AlertSeverity severity, double alertScore, TrendAnalysisResult trend) {
        PatternAlert alert = new PatternAlert();
        alert.setLifeEntityId(lifeEntityId);
        alert.setTitle(title);
        alert.setDescription(description);
        alert.setSeverity(severity);
        alert.setStatus(AlertStatus.NEW);
        alert.setTriggeredAt(LocalDateTime.now());
        alert.setAlertScore(Math.min(alertScore, 1.0));
        alert.setTrendChangeRate(trend.getSlope());
        
        // 生成建议措施
        String recommendations = generateRecommendations(title, trend);
        alert.setRecommendedActions(recommendations);
        
        // 预测影响
        String predictedImpact = predictImpact(title, trend);
        alert.setPredictedImpact(predictedImpact);
        
        // 设置元数据
        Map<String, Object> metadata = new HashMap<>();
        metadata.put("trend_slope", trend.getSlope());
        metadata.put("trend_intercept", trend.getIntercept());
        metadata.put("r_squared", trend.getRSquared());
        metadata.put("analysis_type", "trend_analysis");
        alert.setMetadata(jsonUtils.toJson(metadata));
        
        return alert;
    }

    /**
     * 生成建议措施
     */
    private String generateRecommendations(String alertTitle, TrendAnalysisResult trend) {
        StringBuilder recommendations = new StringBuilder();
        
        if (alertTitle.contains("置信度")) {
            if (trend.getSlope() < 0) {
                recommendations.append("1. 检查生命体的学习机制是否正常运行\n");
                recommendations.append("2. 增加训练数据或调整学习参数\n");
                recommendations.append("3. 评估环境变化对生命体的影响\n");
            } else {
                recommendations.append("1. 继续保持当前的优化策略\n");
                recommendations.append("2. 监控是否存在过拟合风险\n");
            }
        } else if (alertTitle.contains("频率")) {
            if (trend.getSlope() > 0) {
                recommendations.append("1. 监控系统资源使用情况\n");
                recommendations.append("2. 评估活动频率增加的原因\n");
                recommendations.append("3. 考虑是否需要负载均衡\n");
            } else {
                recommendations.append("1. 检查生命体是否处于休眠状态\n");
                recommendations.append("2. 评估外部刺激是否充足\n");
            }
        } else if (alertTitle.contains("异常")) {
            recommendations.append("1. 立即进行详细的异常行为分析\n");
            recommendations.append("2. 检查是否存在安全威胁\n");
            recommendations.append("3. 考虑启动应急响应机制\n");
        } else if (alertTitle.contains("多样性")) {
            if (trend.getSlope() < 0) {
                recommendations.append("1. 增加环境刺激的多样性\n");
                recommendations.append("2. 检查学习机制是否过于专化\n");
            } else {
                recommendations.append("1. 监控多样性增加是否影响效率\n");
                recommendations.append("2. 评估是否需要引导专业化发展\n");
            }
        }
        
        return recommendations.toString();
    }

    /**
     * 预测影响
     */
    private String predictImpact(String alertTitle, TrendAnalysisResult trend) {
        StringBuilder impact = new StringBuilder();
        
        double changeRate = Math.abs(trend.getSlope());
        
        if (changeRate > CRITICAL_CHANGE_THRESHOLD) {
            impact.append("高影响：");
        } else if (changeRate > SIGNIFICANT_CHANGE_THRESHOLD) {
            impact.append("中等影响：");
        } else {
            impact.append("低影响：");
        }
        
        if (alertTitle.contains("置信度") && trend.getSlope() < 0) {
            impact.append("可能导致决策质量下降，影响生命体的整体表现");
        } else if (alertTitle.contains("异常")) {
            impact.append("可能存在安全风险，需要立即关注");
        } else if (alertTitle.contains("频率")) {
            if (trend.getSlope() > 0) {
                impact.append("可能导致资源消耗增加");
            } else {
                impact.append("可能表明生命体活力下降");
            }
        }
        
        return impact.toString();
    }

    /**
     * 获取趋势预警统计
     */
    public Map<String, Object> getTrendAlertStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        try {
            LocalDateTime since = LocalDateTime.now().minus(7, ChronoUnit.DAYS);
            List<PatternAlert> recentAlerts = patternAlertRepository.findByTimeRange(since, LocalDateTime.now());
            
            // 按严重程度统计
            Map<AlertSeverity, Long> severityCount = recentAlerts.stream()
                    .collect(Collectors.groupingBy(PatternAlert::getSeverity, Collectors.counting()));
            
            // 按状态统计
            Map<AlertStatus, Long> statusCount = recentAlerts.stream()
                    .collect(Collectors.groupingBy(PatternAlert::getStatus, Collectors.counting()));
            
            // 趋势类型统计
            Map<String, Long> trendTypeCount = recentAlerts.stream()
                    .collect(Collectors.groupingBy(PatternAlert::getTitle, Collectors.counting()));
            
            statistics.put("total_alerts", recentAlerts.size());
            statistics.put("severity_distribution", severityCount);
            statistics.put("status_distribution", statusCount);
            statistics.put("trend_type_distribution", trendTypeCount);
            statistics.put("analysis_period_days", 7);
            
        } catch (Exception e) {
            log.error("获取趋势预警统计时发生错误", e);
        }
        
        return statistics;
    }

    // 内部数据类
    private static class TimeSeriesPoint {
        private final double x;
        private final double y;

        public TimeSeriesPoint(double x, double y) {
            this.x = x;
            this.y = y;
        }

        public double getX() { return x; }
        public double getY() { return y; }
    }

    private static class TrendAnalysisResult {
        private final double slope;
        private final double intercept;
        private final double rSquared;

        public TrendAnalysisResult(double slope, double intercept, double rSquared) {
            this.slope = slope;
            this.intercept = intercept;
            this.rSquared = rSquared;
        }

        public double getSlope() { return slope; }
        public double getIntercept() { return intercept; }
        public double getRSquared() { return rSquared; }
    }
}